﻿// Decompiled with JetBrains decompiler
// Type: DnProcessSimulateCommands.DetailedDataUtils.CApDduUnloadDetailedDataBaseApp
// Assembly: DnProcessSimulateCommands, Version=2402.0.0.890, Culture=neutral, PublicKeyToken=null
// MVID: A885D881-AEDF-447E-852A-6F13102E089C
// Assembly location: C:\Program Files\Tecnomatix_2402\eMPower\DotNetCommands\DnProcessSimulateCommands.dll

using System;
using System.Collections.ObjectModel;
using System.Text;
using System.Windows.Forms;
using Tecnomatix.Engineering;
using Tecnomatix.Engineering.CommandParameters;


namespace DnProcessSimulateCommands.DetailedDataUtils;

internal abstract class CApDduUnloadDetailedDataBaseApp
{
  internal CUiDtuBaseEnabler m_enabler;
  protected string m_commandName;
  protected string m_removeDetailedLevelWarning;
  protected string m_failedUnloadComponentMsg;
  protected bool m_isMessagesInit;
  private bool m_isStudyExecuted;

  internal CUiDtuBaseEnabler CommandEnabler => this.m_enabler;

  internal string CommandName
  {
    get => this.m_commandName;
    set => this.m_commandName = value;
  }

  internal string RemoveDetailedLevelWarning
  {
    get => this.m_removeDetailedLevelWarning;
    set => this.m_removeDetailedLevelWarning = value;
  }

  protected string FailedUnloadComponentMsg
  {
    get => this.m_failedUnloadComponentMsg;
    set => this.m_failedUnloadComponentMsg = value;
  }

  internal bool IsStudyExecuted
  {
    get => this.m_isStudyExecuted;
    set => this.m_isStudyExecuted = value;
  }

  public void Execute(TxMultipleObjectParameters param)
  {
    this.InitMessages();
    TxObjectList selectedObjects = TxApplication.ActiveSelection.GetItems();
    bool exeSelection = true;
    if (param != null)
    {
      selectedObjects = param.Objects;
      exeSelection = false;
    }
    if (((Collection<ITxObject>) selectedObjects).Count < 1)
      return;
    Cursor oldCursor = CApDduUnloadDetailedDataBaseApp.PreExecute(exeSelection);
    bool loadExec = this.ExecuteWihMessages(selectedObjects);
    CApDduUnloadDetailedDataBaseApp.PostExecute(selectedObjects, exeSelection, loadExec, oldCursor);
  }

  private static Cursor PreExecute(bool exeSelection)
  {
    Cursor cursor = (Cursor) null;
    if (exeSelection)
    {
      cursor = Cursor.Current;
      Cursor.Current = Cursors.WaitCursor;
    }
    return cursor;
  }

  private bool ExecuteWihMessages(TxObjectList selectedObjects)
  {
    bool flag = true;
    TxApplication.ActiveUndoManager.ClearAllTransactions();
    TxObjectList objectsToHandle = this.GetObjectsToHandle(selectedObjects);
    StringBuilder stringBuilder = new StringBuilder();
    foreach (ITxComponent selectedComponent in (Collection<ITxObject>) this.GetSelectedComponents(objectsToHandle))
    {
      if (selectedComponent != null && this.HasUnpreservedReferencedEntities(selectedComponent) && this.CommandEnabler.AllowedComponentRepresentation(selectedComponent))
      {
        if (stringBuilder.Length > 0)
          stringBuilder.Append(", ");
        stringBuilder.Append(((ITxObject) selectedComponent).Name);
      }
    }
    if (stringBuilder.Length > 0)
      flag = TxMessageBox.Show(string.Format(this.RemoveDetailedLevelWarning, (object) stringBuilder.ToString()), this.CommandName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes;
    if (flag)
    {
      string empty = string.Empty;
      this.UnloadEntityLevelForCollection(objectsToHandle, ref empty);
      if (empty.Length > 2)
      {
        int num = (int) TxMessageBox.Show(string.Format(this.FailedUnloadComponentMsg, (object) empty.Remove(empty.Length - 2)), this.CommandName, MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
      }
    }
    return flag;
  }

  private static void PostExecute(
    TxObjectList selectedObjects,
    bool exeSelection,
    bool loadExec,
    Cursor oldCursor)
  {
    if (loadExec)
      TxApplication.ActiveUndoManager.ClearAllTransactions();
    if (!exeSelection)
      return;
    if (loadExec)
    {
      TxApplication.ActiveSelection.SetItems(selectedObjects);
      TxApplication.RefreshDisplay();
    }
    Cursor.Current = oldCursor;
  }

  private TxObjectList GetObjectsToHandle(TxObjectList selectedObjects)
  {
    TxPhysicalRoot physicalRoot = TxApplication.ActiveDocument.PhysicalRoot;
    TxObjectList objectsToHandle;
    if (((Collection<ITxObject>) selectedObjects).Contains((ITxObject) physicalRoot))
    {
      this.IsStudyExecuted = true;
      objectsToHandle = physicalRoot.GetAllDescendants((ITxTypeFilter) this.CommandEnabler.ComponentFilter);
    }
    else
      objectsToHandle = new TxObjectList(selectedObjects);
    return objectsToHandle;
  }

  private void UnloadEntityLevelForCollection(
    TxObjectList selectedObjects,
    ref string componentsFailedToUnload)
  {
    TxObjectList txObjectList = new TxObjectList();
    TxObjectList currentObjList;
    if (this.IsStudyExecuted)
    {
      currentObjList = selectedObjects;
    }
    else
    {
      this.CollectSubEquipmentComponents(ref selectedObjects);
      currentObjList = this.CollectComponentsToLoad(selectedObjects);
      this.CollectComponentsFromLogicalCollections(selectedObjects, currentObjList);
    }
    this.LoadComponents(currentObjList, ref componentsFailedToUnload);
  }

  private void CollectComponentsFromLogicalCollections(
    TxObjectList selectedObjects,
    TxObjectList currentObjList)
  {
    TxTypeFilter componentFilter = this.CommandEnabler.ComponentFilter;
    foreach (ITxObject selectedObject in (Collection<ITxObject>) selectedObjects)
    {
      if (selectedObject is ITxLogicalCollection)
      {
        foreach (ITxObject allDescendant in (Collection<ITxObject>) (selectedObject as ITxObjectCollection).GetAllDescendants((ITxTypeFilter) componentFilter))
        {
          if (!((Collection<ITxObject>) currentObjList).Contains(allDescendant))
            ((Collection<ITxObject>) currentObjList).Add(allDescendant);
        }
      }
    }
  }

  private void CollectSubEquipmentComponents(ref TxObjectList selectedObjects)
  {
    TxObjectList txObjectList = new TxObjectList();
    foreach (ITxObject compoundEquipment in (Collection<ITxObject>) selectedObjects)
    {
      TxObjectList subEquipments = new TxObjectList();
      if (compoundEquipment is ITxComponent itxComponent && itxComponent.IsEquipment)
      {
        this.GetSubEquipments(compoundEquipment, out subEquipments);
        ((TxObjectList<ITxObject>) txObjectList).Append((TxObjectList<ITxObject>) subEquipments);
      }
    }
    foreach (ITxObject itxObject in (Collection<ITxObject>) txObjectList)
    {
      if (!((Collection<ITxObject>) selectedObjects).Contains(itxObject))
        ((Collection<ITxObject>) selectedObjects).Add(itxObject);
    }
  }

  private TxObjectList CollectComponentsToLoad(TxObjectList selectedObjects)
  {
    TxObjectList load = new TxObjectList();
    foreach (ITxObject selectedObject in (Collection<ITxObject>) selectedObjects)
    {
      if (selectedObject is ITxCompound)
      {
        TxTypeFilter componentFilter = this.CommandEnabler.ComponentFilter;
        if (selectedObject is ITxObjectCollection objectCollection)
          ((TxObjectList<ITxObject>) load).Append((TxObjectList<ITxObject>) objectCollection.GetAllDescendants((ITxTypeFilter) componentFilter));
      }
      else if (selectedObject is ITxComponent)
        ((Collection<ITxObject>) load).Add(selectedObject);
    }
    return load;
  }

  private void LoadComponents(TxObjectList currentObjList, ref string componentsFailedToUnload)
  {
    foreach (ITxObject currentObj in (Collection<ITxObject>) currentObjList)
    {
      if (currentObj is ITxStorable itxStorable)
      {
        TxLibraryStorage storageObject = itxStorable.StorageObject as TxLibraryStorage;
        if (TxStorage.op_Inequality((TxStorage) storageObject, (TxStorage) null))
        {
          try
          {
            if (this.CommandEnabler.AllowedComponentRepresentation(currentObj as ITxComponent))
              this.UnloadDetailed(storageObject);
          }
          catch (Exception ex)
          {
            if (this.CommandEnabler.AllowedComponentRepresentation(currentObj as ITxComponent))
              componentsFailedToUnload = $"{componentsFailedToUnload}{((ITxObject) itxStorable).Name}, ";
          }
        }
      }
    }
  }

  private void GetSubEquipments(ITxObject compoundEquipment, out TxObjectList subEquipments)
  {
    subEquipments = new TxObjectList();
    if (!(compoundEquipment is ITxObjectCollection objectCollection))
      return;
    TxTypeFilter txTypeFilter = new TxTypeFilter(typeof (ITxComponent));
    subEquipments = objectCollection.GetAllDescendants((ITxTypeFilter) txTypeFilter);
  }

  private TxObjectList GetSelectedComponents(TxObjectList selectedObjects)
  {
    TxObjectList selectedComponents = new TxObjectList();
    TxObjectList txObjectList = new TxObjectList();
    TxTypeFilter txTypeFilter = new TxTypeFilter(typeof (ITxComponent));
    foreach (ITxObject selectedObject in (Collection<ITxObject>) selectedObjects)
    {
      switch (selectedObject)
      {
        case ITxCompound _:
          if (selectedObject is ITxObjectCollection objectCollection1)
          {
            ((TxObjectList<ITxObject>) selectedComponents).Append((TxObjectList<ITxObject>) objectCollection1.GetAllDescendants((ITxTypeFilter) txTypeFilter));
            continue;
          }
          continue;
        case ITxComponent _:
          ((Collection<ITxObject>) selectedComponents).Add(selectedObject);
          if (selectedObject is ITxComponent itxComponent && itxComponent.IsEquipment)
          {
            ITxObjectCollection objectCollection2 = itxComponent as ITxObjectCollection;
            ((TxObjectList<ITxObject>) selectedComponents).Append((TxObjectList<ITxObject>) objectCollection2.GetAllDescendants((ITxTypeFilter) txTypeFilter));
            continue;
          }
          continue;
        case ITxLogicalCollection _:
          ((Collection<ITxObject>) txObjectList).Add(selectedObject);
          continue;
        default:
          continue;
      }
    }
    foreach (ITxLogicalCollection logicalCollection in (Collection<ITxObject>) txObjectList)
    {
      foreach (ITxObject allDescendant in (Collection<ITxObject>) (logicalCollection as ITxObjectCollection).GetAllDescendants((ITxTypeFilter) txTypeFilter))
      {
        if (!((Collection<ITxObject>) selectedComponents).Contains(allDescendant))
          ((Collection<ITxObject>) selectedComponents).Add(allDescendant);
      }
    }
    return selectedComponents;
  }

  protected virtual void InitMessages()
  {
    if (this.m_isMessagesInit)
      return;
    this.RemoveDetailedLevelWarning = string.Empty;
    this.FailedUnloadComponentMsg = string.Empty;
    this.CommandName = string.Empty;
    this.m_isMessagesInit = true;
  }

  protected abstract bool HasUnpreservedReferencedEntities(ITxComponent component);

  protected abstract void UnloadDetailed(TxLibraryStorage libraryStorageObject);
}
